package com.zdya.combatdocuments.util;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.datatypes.AbiTypes;
import org.web3j.abi.datatypes.Function;


import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EthRPCUtil {

    public static void main123(String[] args) {

        String ip = "192.168.3.215";
        String enode = "enode://2e927002c5cfa4fd373a73527575189f606cea9ba6705c596478fe3d7af17c921f69d09f71cc6b83f76b9e1161a16c5c79da9b1c2ab3681f96fafdf578d6178c@192.168.3.162:30303?discport=0";

//
//        boolean b = addPeer(ip, enode);
//        System.out.println(b);
        long l = System.currentTimeMillis();
        System.out.println(getEnodes(ip));

        long l1 = System.currentTimeMillis();

        System.out.println(getEnodes("127.0.0.1"));
        long l2 = System.currentTimeMillis();

        System.out.println(l1-l);
        System.out.println(l2-l1);

//  admin_nodeInfo_protocols_eth_config_chainId


    }


    /**
     * 调用JSONRPC admin_addPeer 添加节点
     * @param peerAddress 节点ip地址
     * @param enode 需要同步的节点的enode
     * @return
     */
    public static boolean addPeer(String peerAddress, String enode){

        try {
            String address = "http://" + peerAddress + ":8545";
            String result = doPostOrGet( address, "{\"jsonrpc\":\"2.0\",\"method\":\"admin_addPeer\",\"params\":[\""+enode+"\"],\"id\":67}" );
            System.out.println("******************************"+result);
            if (result!=null){
                // HashMap<String,Object> hashMap = JSON.parseObject(result, HashMap.class);
                // HashMap<String,Object> resultMap =JSON.parseObject(hashMap.get( "result" ).toString(), HashMap.class);
                // String enodeA = resultMap.get( "enode" ).toString();
                // //修改enodeIP
                // int loc = enodeA.indexOf("@");
                // String newStr = enodeA.substring(0,loc);
                // String enodeAddress = newStr+"@"+peerAddress+":30303?discport=0";
                try {
                    Map hashMap = JSONUtil.parseObj(result);
                    return Boolean.valueOf( String.valueOf(hashMap.get("result")));
                }catch (Exception e){
                    return false;
                }
            }else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 调用JSONRPC eth_coinbase 获取挖矿奖励地址
     * @param peerAddress 节点ip地址
     * @return
     */
    public static String getCoinBase(String peerAddress){

       try {
           String address = "http://" + peerAddress + ":8545";
           String result = doPostOrGet( address, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_coinbase\",\"params\":[],\"id\":67}" );
           if (result!=null){
               try {
                   Map hashMap = JSONUtil.parseObj(result);
                   if(hashMap.get("result") !=null && !"".equals(hashMap.get("result"))){
                       return String.valueOf(hashMap.get("result"));
                   }else {
                       return "";
                   }
               }catch (Exception e){
                   e.printStackTrace();
                   return "";
               }
           }else {
               return "";
           }
       }catch (Exception e){
           e.printStackTrace();
           return "";
       }
    }

    public static void main(String[] args) {
        String enodes = getEnodes("127.0.0.1");
        System.out.println(enodes);
    }
    /**
     * 调用JSONRPC admin_nodeInfo 获取enode
     * @param peerAddress
     * @return
     */
    public static String getEnodes(String peerAddress){
        String address = "http://" + peerAddress + ":8545";
        String result = doPostOrGet( address, "{\"jsonrpc\":\"2.0\",\"method\":\"admin_nodeInfo\",\"params\":[],\"id\":67}" );
        if (result!=null){
            try {
                HashMap<String, Object> hashMap = JSONUtil.toBean(result, HashMap.class);
                HashMap<String, Object> resultMap =JSONUtil.toBean(hashMap.get( "result" ).toString(), HashMap.class);
                String enode = resultMap.get( "enode" ).toString();
                //修改enodeIP
                int loc = enode.indexOf("@");
                String newStr = enode.substring(0,loc);
                String enodeAddress = newStr+"@"+peerAddress+":30303?discport=0";
                return enodeAddress;
            }catch (Exception e){
                e.printStackTrace();
                return "";
            }

        }else {
            return "";
        }
    }

    /**
     * 调用JSONRPC eth_syncing 获取当前的同步状态
     * @param peerAddress
     * @return
     */
    public static Boolean getSyncStatus(String peerAddress){
        try {
            String address = "http://" + peerAddress + ":8545";
            String result = doPostOrGet( address, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_syncing\",\"params\":[],\"id\":67}" );
            if (result!=null){
                Map hashMap = JSONUtil.parseObj(result);
                if(hashMap.get("result") !=null && !"".equals(hashMap.get("result"))){
                    try {
                        JSONObject jsonObject = JSONUtil.parseObj(hashMap.get("result"));
                        if(jsonObject.size() == 0){
                            return false;
                        }else {
                            return true;
                        }
                    }catch (Exception e){
                        return false;
                    }

                }else {
                    return false;
                }
            }else {
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public static boolean ethCall(String peerAddress){
        try {
            String address = "http://" + peerAddress + ":8545";
            List inputParameters = new ArrayList();
            inputParameters.add(ReflectUtil.newInstance(AbiTypes.getType("address"), "0xa0f1ecd5eec7be3cf90d98f12b7407c3ef5c894b"));
            Function function = new Function("getBalance", inputParameters, new ArrayList<>());

            String encodedFunction = FunctionEncoder.encode(function);
            String result = doPostOrGet( address, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\n" +
                    "            \"to\": \"0x7aeed44a928378bc48e89595b9ed3d515eb324f0\",\n" +
                    "            \"data\": \""+encodedFunction+"\"\n" +
                    "        },\n" +
                    "        \"latest\"],\"id\":67}" );
            if (result!=null){
                Map hashMap = JSONUtil.parseObj(result);
                if(hashMap.get("result") !=null && !"".equals(hashMap.get("result"))){
                    try {
                        return Boolean.valueOf( String.valueOf(hashMap.get("result")));
                    }catch (Exception e){
                        return false;
                    }

                }else {
                    return false;
                }
            }else {
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }



    public static void main11(String[] args) {
         System.out.println(getSyncStatus("192.168.3.110"));
//         Map m = new HashMap();
//         m.put("aa", null);
//        System.out.println("null".equals(String.valueOf(m.get("aa"))));
//        System.out.println(StringUtils.isNotBlank(String.valueOf(m.get("aa"))));
//        ethCall("192.168.3.107");
    }

    /**
     *java Http
     */
    private static String doPostOrGet(String pathUrl, String data) {
        OutputStreamWriter out = null;
        BufferedReader br = null;
        String result = "";
        try {
            URL url = new URL( pathUrl );
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //请求方式
            conn.setRequestMethod( "POST" );
            //conn.setRequestMethod("GET");

            //设置通用的请求属性
            conn.setRequestProperty( "accept", "*/*" );
            conn.setRequestProperty( "connection", "Keep-Alive" );
            conn.setRequestProperty( "user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" );
            conn.setRequestProperty( "Content-Type", "application/json;charset=utf-8" );

            //DoOutput设置是否向httpUrlConnection输出，DoInput设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            conn.setDoOutput( true );
            conn.setDoInput( true );

            /**
             * 下面的三句代码，就是调用第三方http接口
             */
            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter( conn.getOutputStream(), "UTF-8" );
            //发送请求参数即数据
            out.write( data );
            //flush输出流的缓冲
            out.flush();

            /**
             * 下面的代码相当于，获取调用第三方http接口后返回的结果
             */
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader( new InputStreamReader( is ) );
            String str = "";
            while ((str = br.readLine()) != null) {
                result += str;
            }
            // System.out.println(result);
            //关闭流
            is.close();
            //断开连接，disconnect是在底层tcp socket链接空闲时才切断，如果正在被其他线程使用就不切断。
            conn.disconnect();

            return result;

        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}
